package org.bing.engine.statistic.container.jetty;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.bing.engine.statistic.domain.ContainerStatistics;
import org.bing.engine.statistic.helper.JsonHelper;
import org.bing.engine.statistic.helper.JvmStatHelper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.thread.ThreadPool;

public class StatisticHandler extends org.eclipse.jetty.server.handler.HandlerCollection {
    public static final String ADMIN_URI = "/x-engine";
    private long lastRequestTime = 0;
    private long lastRequestNum = 0;
    private long requestNum = 0;

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
            ServletException {
        requestNum++;
        if (target != null && ADMIN_URI.startsWith(target)) {
            doManage(target, baseRequest, request, response);
        } else {
            super.handle(target, baseRequest, request, response);
        }
    }

    private void doManage(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
            ServletException {
        String cmd = baseRequest.getParameter("cmd");
        if ("shutdown".equalsIgnoreCase(cmd)) {
            doShutdown();
        } else if ("statistic".equalsIgnoreCase(cmd)) {
            String stat = doStatistic();
            response.getWriter().print(stat);
            response.flushBuffer();
        } else if ("state".equalsIgnoreCase(cmd)) {
            response.getWriter().print(STARTED.equals(this.getState()) ? "OK" : "ERROR");
            response.flushBuffer();
        } else {
            // unknown request, handle by super
            super.handle(target, baseRequest, request, response);
        }
    }

    private String doStatistic() {
        ContainerStatistics stat = new ContainerStatistics();
        ThreadPool tp = this.getServer().getThreadPool();
        stat.setTotalThreadNum(tp.getThreads());
        stat.setIdleThreadNum(tp.getIdleThreads());
        stat.setMemUsage(JvmStatHelper.getMemoryUsage());
        stat.setCpuUsage(JvmStatHelper.getCpuUsage());
        // calc qps use history data
        long now = System.currentTimeMillis();
        if (lastRequestTime > 0) {
            int queryPerSec = (int) ((requestNum - lastRequestNum) * 1000 / (now - lastRequestTime));
            stat.setQueryPerSec(queryPerSec);
        }
        lastRequestNum = requestNum;
        lastRequestTime = now;
        // calc traffic for request and response // TODO impl
        stat.setInTrafficPerSec(1);
        stat.setOutTrafficPerSec(1);
        // encode to json
        return JsonHelper.toJsonString(stat);
    }

    private void doShutdown() {
        try {
            this.getServer().stop();
        } catch (Exception e) {
            // ignore
        }
        System.gc();
        System.exit(0);
    }
}
